package main

import (
	"fmt"
	"github.com/tarm/serial"
	//"iot-base/common/modbus3"
	"iot-base/common/modbus"
	"iot-base/devc/common/loader"
	"strconv"
	"strings"
	"time"
)

func GetClient(protocol *loader.Protocol) modbus.Client {
	if protocol == nil {
		return nil
	}
	fmt.Println("protocol.Params:", protocol.Params)
	switch strings.ToLower(protocol.ProtocolType) {
	case "rtu":
		v, ok := protocol.Params["Name"].(string)
		if !ok {
			fmt.Println("Name err:", protocol.Params["Name"])
			return nil
		}
		handler := modbus.NewRTUClientHandler(v)
		n, ok := protocol.Params["BaudRate"].(string)
		if !ok {
			fmt.Println("BaudRate err")
			return nil
		}
		res, _ := strconv.ParseInt(n, 10, 0)
		handler.Baud = int(res)
		n, ok = protocol.Params["DataBits"].(string)
		if !ok {
			fmt.Println("DataBits err")
			return nil
		}
		res, _ = strconv.ParseInt(n, 10, 0)
		handler.Size = byte(res)
		v, ok = protocol.Params["Parity"].(string)
		if !ok {
			fmt.Println("Parity err")
			return nil
		}
		handler.Parity = ParseParity(v)
		n, ok = protocol.Params["StopBits"].(string)
		if !ok {
			fmt.Println("StopBits err")
			return nil
		}
		handler.StopBits = ParseStopBit(n)
		handler.ReadTimeout = 500 * time.Millisecond
		handler.SlaveId = protocol.SlaveId
		err := handler.Connect()
		if err != nil {
			fmt.Println("connect err:", err)
			return nil
		}
		//defer handler.Close()
		client := modbus.NewClient(handler)
		return client
	case "tcp":
		ip, ok := protocol.Params["IP"].(string)
		if !ok {
			fmt.Println("IP err")
			return nil
		}
		port, ok := protocol.Params["Port"].(string)
		if !ok {
			fmt.Println("port err")
			return nil
		}
		handler := modbus.NewTCPClientHandler(fmt.Sprintf("%s:%s", ip, port))
		handler.SlaveId = protocol.SlaveId
		handler.Timeout = 500 * time.Millisecond
		err := handler.Connect()
		if err != nil {
			fmt.Println("tcp connect err!")
		}
		//defer handler.Close()
		client := modbus.NewClient(handler)
		return client
	case "asc":
		ip, ok := protocol.Params["IP"].(string)
		if !ok {
			fmt.Println("IP err")
			return nil
		}
		port, ok := protocol.Params["Port"].(string)
		if !ok {
			fmt.Println("port err")
			return nil
		}
		handler := modbus.NewASCIIClientHandler(fmt.Sprintf("%s:%s", ip, port))
		handler.SlaveId = protocol.SlaveId
		handler.ReadTimeout = 500 * time.Millisecond
		err := handler.Connect()
		if err != nil {
			fmt.Println("tcp connect err!")
		}
		//defer handler.Close()
		client := modbus.NewClient(handler)
		return client
	case "dtu":
		ip, ok := protocol.Params["IP"].(string)
		if !ok {
			fmt.Println("IP err")
			return nil
		}
		port, ok := protocol.Params["Port"].(string)
		if !ok {
			fmt.Println("port err")
			return nil
		}
		handler := modbus.NewRTUTCPClientHandler(fmt.Sprintf("%s:%s", ip, port))
		handler.SlaveId = protocol.SlaveId
		handler.Timeout = 500 * time.Millisecond
		err := handler.Connect()
		if err != nil {
			fmt.Println("tcp connect err!")
		}
		//defer handler.Close()
		client := modbus.NewClient(handler)
		return client
	case "tcprtu":
		ip, ok := protocol.Params["IP"].(string)
		if !ok {
			fmt.Println("IP err")
			return nil
		}
		port, ok := protocol.Params["Port"].(string)
		if !ok {
			fmt.Println("port err")
			return nil
		}
		name, ok := protocol.Params["Name"].(string)
		if !ok {
			fmt.Println("Name err:", protocol.Params["Name"])
			return nil
		}
		BaudRate, ok := protocol.Params["BaudRate"].(string)
		if !ok {
			fmt.Println("BaudRate err")
			return nil
		}
		baud, _ := strconv.ParseInt(BaudRate, 10, 0)
		DataBits, ok := protocol.Params["DataBits"].(string)
		if !ok {
			fmt.Println("DataBits err")
			return nil
		}
		databit, _ := strconv.ParseUint(DataBits, 10, 0)
		Parity, ok := protocol.Params["Parity"].(string)
		if !ok {
			fmt.Println("Parity err")
			return nil
		}
		parity := ParseParity(Parity)
		StopBits, ok := protocol.Params["StopBits"].(string)
		if !ok {
			fmt.Println("StopBits err")
			return nil
		}
		stop := ParseStopBit(StopBits)
		handler := modbus.NewDTUClientHandler(fmt.Sprintf("%s:%s", ip, port))
		handler.Name = name
		handler.Baud = int(baud)
		handler.Parity = parity
		handler.Size = uint8(databit)
		handler.StopBits = stop
		handler.SlaveId = protocol.SlaveId
		handler.Timeout = 200 * time.Millisecond
		err := handler.Connect()
		if err != nil {
			fmt.Println("tcp connect err!")
		}
		//defer handler.Close()
		client := modbus.NewClient(handler)
		return client
	default:
		fmt.Println("modbus type err！")
		return nil
	}
}

func ParseParity(in string) serial.Parity {
	switch strings.ToUpper(in) {
	case "N":
		return serial.ParityNone
	case "O":
		return serial.ParityOdd
	case "E":
		return serial.ParityEven
	case "M":
		return serial.ParityMark
	case "S":
		return serial.ParitySpace
	default:
		return serial.ParityNone
	}
}

func ParseStopBit(in string) serial.StopBits {
	switch in {
	case "1":
		return serial.Stop1
	case "2":
		return serial.Stop2
	case "half":
		return serial.Stop1Half
	default:
		return serial.Stop1
	}
}
